/**
 * Location handler.
 * 
 * @author Alican Ozgoren
 * @version 12/14/2012
 */

package edu.brockport.shuttleapp;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class MyLocation 
{
    private LocationManager locationManager;
    LocationResult locationResult;
    private boolean gpsEnabled = false;
    private boolean networkEnabled = false;
    private Context context;
    
    //----------------------------------------------------------
    public MyLocation(Context context, LocationResult result)
    {
    	this.context = context;
    	locationResult = result;
    }

    //----------------------------------------------------------
    public MyResult checkServices()
    {
        if(locationManager == null)
        	locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

        try
        {
        	gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        }
        catch(Exception ex)
        {
        	return new MyResult(Utilities.UNEXPECTED_ERROR, null, "Unexpected error!");
        }
        
        try
        {
        	networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        }
        catch(Exception ex)
        {
        	return new MyResult(Utilities.UNEXPECTED_ERROR, null, "Unexpected error!");
        }

        
        if(!gpsEnabled && !networkEnabled)
        	return new MyResult(Utilities.LOCATION_DISABLED, null,
        			"Your phone's GPS feature is off. We cannot track your current " +
					"location without the GPS feature. If you want us to choose your " +
					"source stop automatically, you need to turn the GPS feature " +
					"on.");
        
        return new MyResult(Utilities.NO_ERROR, null, null);
    }
    
    //----------------------------------------------------------
    public void requestLocationUpdates()
    {
    	if(gpsEnabled)
        	locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
        
        if(networkEnabled)
        	locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
    }

    //----------------------------------------------------------
    LocationListener locationListenerGps = new LocationListener() 
    {
        public void onLocationChanged(Location location) 
        {
            locationResult.gotLocation(location);
            locationManager.removeUpdates(this);
            locationManager.removeUpdates(locationListenerNetwork);
        }
        
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    LocationListener locationListenerNetwork = new LocationListener() 
    {
        public void onLocationChanged(Location location) 
        {
        	locationResult.gotLocation(location);
            locationManager.removeUpdates(this);
            locationManager.removeUpdates(locationListenerGps);
        }
        
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };
    
    //----------------------------------------------------------
    public void lookForAccurateData() 
    {
    	locationManager.removeUpdates(locationListenerGps);
    	locationManager.removeUpdates(locationListenerNetwork);

        Location netLoc = null, gpsLoc = null;
         
        if(gpsEnabled)
        	gpsLoc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
         
        if(networkEnabled)
            netLoc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

        // Use the newest one
        if(gpsLoc != null && netLoc != null)
        {
            if(gpsLoc.getTime() > netLoc.getTime())
            	locationResult.gotLocation(gpsLoc);
            
            else
            	locationResult.gotLocation(netLoc);

            return;
        }

        if(gpsLoc != null)
        {
        	locationResult.gotLocation(gpsLoc);
            return;
        }
         
        if(netLoc != null)
        {
        	locationResult.gotLocation(netLoc);
            return;
        }
         
        locationResult.gotLocation(null);
    }
    
    //----------------------------------------------------------
    public static abstract class LocationResult
    {
        public abstract void gotLocation(Location location);
    }
}